#include "msg_queue.h"
#include "stdio.h"
#include "c_mutex.h"
STRUCT_MS_QUEUE msg_queue = { 0 };
STRUCT_MS msg_space_queue[MSQ_MAX_QUEUE_LEN];

int msqInit()
{
	msg_queue.start = 0;
	msg_queue.end = 0;
	msg_queue.allFull = 0;
	msg_queue.queue = msg_space_queue;
	msg_queue.size = MSQ_MAX_QUEUE_LEN;
	return 0;
}

int msqPut(STRUCT_MS *msg)
{
	//single thread doesn't need mutex lock
	if (msg_queue.allFull || msg_queue.queue == NULL) return -1;
	msg_queue.queue[msg_queue.end] = *msg;
	msg_queue._len++;
	msg_queue.end = (msg_queue.end + 1) % msg_queue.size;
	if (msg_queue.end == msg_queue.start) {
		msg_queue.allFull = 1;
	}
	return 0;
}

int msqPopBack(STRUCT_MS *msg)
{
	if (msg_queue._len < 1) {
		return -1;
	}
	int n = msg_queue.end - 1 + msg_queue.size;
	msg_queue.end = n % msg_queue.size;
	msg_queue._len--;
	return 0;
}

int msqRemove(int n)
{
	if (n <= 0) {
		return 0;
	}
	if (((msg_queue.start == msg_queue.end) && !msg_queue.allFull) ||
		(n > msg_queue._len)) {	/* too many requested */
		return -1;
	}
	msg_queue.start = (msg_queue.start + n) % msg_queue.size;
	msg_queue.allFull = 0;
	msg_queue._len -= n;
	return 0;
}

int msqLen()
{
	return msg_queue._len;
}

STRUCT_MS *msqItem(int n)
{
	if ((n < 0) || (n >= msg_queue._len) || msg_queue.queue == NULL) return NULL;
	return &(msg_queue.queue[(msg_queue.start + n) % msg_queue.size]);
}

STRUCT_MS *msqLast()
{
	if (msg_queue._len == 0) {
		return NULL;
	}
	//Fix for negative modulus error
	int n = msg_queue.end - 1 + msg_queue.size;
	return &(msg_queue.queue[n % msg_queue.size]);
}


